<?php

/**
 * ajax actions.
 *
 * @package    baumarktforsibers.kg
 * @subpackage ajax
 * @author     Belitskii Ivan
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class ajaxActions extends sfActions
{
 /**
  * Executes index action
  *
  * @param sfRequest $request A request object
  */
    public function executeIndex(sfWebRequest $request)
    {
        //$this->forward('default', 'module');
    }
    
    /**
     * Function puts
     * name, id, quantity, total_sum, category_id of product selected by user to the cart
     * 
     * @param sfWebRequest $request
     * @return json 
     */
    public function executeOrder(sfWebRequest $request) {
        if($this->getUser()->isAuthenticated() && $request->isXmlHttpRequest()) {
            
            // getting id and quantity of the product from post request            
            $id = $request->getPostParameter('id');
            $quantity = $request->getPostParameter('quantity');
            
            // finding product in the database
            $product = Doctrine_Core::getTable('products')->findOneBy('id', $id);
            
            // getting product name, total sum for product, category id of the product
            $product_name = $product->getName();
            $product_total = $quantity * $product->getPrice();
            $category = $product->getCategory()->getId();
            
            // get current user
            $user = $this->getUser();
            
            // checking if there is and attribute 'orders' in the session of the user
            // if yes, then get it and compare each product with product we are trying to add to the cart
            // by product_id. If product already exists, remove it, and add product with another quantity
            // if no, then add new product
            if ($user->hasAttribute('orders')) {
                $orders = $user->getAttribute('orders');
                foreach ($orders as $key => $value) {
                    if ($key == $id) {
                        unset($orders[$key]);
                    }
                }
                
                // formaulating the array of the product to put into the user's session
                // set array of orders to the session
                $orders[$id] = array($product_name, $quantity, $product_total, $id, $category);
                $user->setAttribute('orders', $orders);
            }
            else {
                // formaulating the array of the product to put into the user's session
                // set array of orders to the session
                $orders[$id] = array($product_name, $quantity, $product_total, $id, $category);
                $user->setAttribute('orders', $orders);
            }
            return $this->renderText(json_encode(array('status'=> true)));
        }
        return $this->renderText(json_encode(array('status'=> false)));
    }
    
    
    /**
     *
     * Function Clears user's cart
     * 
     * @param sfWebRequest $request
     * @return json 
     */
    public function executeClearcart(sfWebRequest $request) {
        if($this->getUser()->isAuthenticated() && $request->isXmlHttpRequest()) {
            
            // get and set session attributes to false
            $user = $this->getUser();
            if ($user->hasAttribute('orders')) {
                $user->setAttribute('orders', false);
            }
            if ($user->hasAttribute('orders_combined')) {
                $user->setAttribute('orders_combined', false);
            }
            return $this->renderText(json_encode(array('status'=> true)));
        }
        return $this->renderText(json_encode(array('status'=> false)));
    }
    
    
    /**
     * Function remove selected product from user's cart
     * 
     * @param sfWebRequest $request
     * @return json 
     */
    public function executeRemoveproduct(sfWebRequest $request) {
        if($this->getUser()->isAuthenticated() && $request->isXmlHttpRequest()) {
            
            // get current user
            $user = $this->getUser();
            
            // get product id from post parameter
            $rid = $request->getParameter('rid');
            
            // flag that is responsible for allowing to remove product from combined_orders
            $status_combined = false;
            
            // if there is an attribute 'orders_combined' then find selected product and remove it from the orders
            // if not, then check 'orders' attribute and remove it from there
            if ($user->hasAttribute('orders_combined')) {
                $orders_combined = $user->getAttribute('orders_combined');
                foreach ($orders_combined as $key => $value) {
                    if ($key == $rid) {
                        unset($orders_combined[$key]);
                        $status_combined = true;
                    }
                }
                // check if 'orders_combined' are empty. If yes, remove it from session,
                // if not, set new array of combined orders to session
                
                count($orders_combined) == 0 ? $user->setAttribute('orders_combined', false) : $user->setAttribute('orders_combined', $orders_combined);
                // finish removing from 'orders_combined'
                
                if ($status_combined) {
                    return $this->renderText(json_encode(array('status'=> true))); 
                }
            }
            if ($user->hasAttribute('orders')) {
                $orders = $user->getAttribute('orders');
                foreach ($orders as $key => $value) {
                    if ($key == $rid) {
                        unset($orders[$key]);
                    }
                }
                // check if 'orders' are empty. If yes, remove it from session,
                // if not, set new array of combined orders to session
                count($orders) == 0 ? $user->setAttribute('orders', false) : $user->setAttribute('orders', $orders);
                return $this->renderText(json_encode(array('status'=> true)));
            }
        }
        return $this->renderText(json_encode(array('status'=> false)));
    }
    
    
    
    /**
     *
     * Function removes orders, selected by user,
     * which can not be delivered
     * 
     * 
     * @param sfWebRequest $request
     * @return json 
     */
    public function executeRemovefromorders(sfWebRequest $request) {
        if($this->getUser()->isAuthenticated() && $request->isXmlHttpRequest()) {
            $product_id = $request->getParameter('pid');
            Doctrine::getTable('orders')->findAndRemoveByProductId($product_id);
            return $this->renderText(json_encode(array('status'=> true)));
        }
        return $this->renderText(json_encode(array('status'=> false)));
    }
    
    /**
     *
     * Function selects all second_dishes and garnirs
     * And returns prepared list of those dishes allowing user to combine them
     * 
     * 
     * @param sfWebRequest $request
     * @return json 
     */
    public function executePrepareOrdersToMerge(sfWebRequest $request) {
        if($this->getUser()->isAuthenticated() && $request->isXmlHttpRequest()) {
            // get current user
            $user = $this->getUser();
            
            // get orders of this user
            $orders = $user->getAttribute('orders');
            
            // information about garnishes, second dishes
            $garnirs = array();
            $second_dishes = array();
            $count_of_garnirs = 0;
            $count_of_second_dishes = 0;
            
            // dividing orders in two types: second dishes, garnishes
            foreach ($orders as $order) {
                $product = Doctrine::getTable('products')->findOneBy('id', $order[3]);
                if ($product->getCategory()->getId() == 5 && $product->getName() != 'Хлеб') {
                    $garnirs[] = $order;
                    $count_of_garnirs += $order[1];
                }
                else if ($product->getCategory()->getId() == 4) {
                    $second_dishes[] = $order;
                    $count_of_second_dishes += $order[1];
                }
            }
            
            // There are two two types of the html output offered to user
            // If quantity of garnishes is more than quantity of second dishes, then
            // User will be able to combine second dishes with garnirs.
            // Otherwise user will be able to combine garnishes with second dishes
            if ($count_of_garnirs >= $count_of_second_dishes) {
                
                // prepating the output to be send via json
                // for each dish there will be generated list containing garnirs
                $send_back = "<table id='merging_table'>";
                foreach ($second_dishes as $dish) {
                    for ($i = 0; $i < $dish[1]; $i++) {
                        $send_back .= "
                            <tr class='merging_tr_second_dishes'>
                                <td><div class='second_dishes' id=".$dish[3].">".$dish[0]."</div></td>";
                        $send_back .= "<td>&nbsp;&nbsp;
                                        <select class='garnir_select'><option value='zero'>без ничего</option>";
                        foreach ($garnirs as $garnir) {
                            $send_back .= "<option value=".$garnir[3]." id=".$garnir[3].">".$garnir[0]." (<span>".$garnir[1]."</span>)</option>";
                        }
                        $send_back .= "</select></td>";
                        $send_back .= "</tr>";
                    }
                }
                $send_back .= "</table>";
                // check whether quantity of second dishes and garnishes is not zero
                // only then user will be able to finish merging
                if ($count_of_garnirs != 0 && $count_of_second_dishes != 0) {
                    $send_back .= "<div id='finish_merging_div'><a href='#' id='finish_merging'>Готово!</a></div>";
                }
            }
            else {
                
                // prepating the output to be send via json
                // for each garnish there will be generated list containing second dishes
                $send_back = "<table id='merging_table'>";
                foreach ($garnirs as $garnir) {
                    for ($i = 0; $i < $garnir[1]; $i++) {
                        $send_back .= "
                            <tr class='merging_tr_garnirs'>
                                <td><div class='garnirs' id=".$garnir[3].">".$garnir[0]."</div></td>";
                        $send_back .= "<td>&nbsp;&nbsp;
                                        <select class='second_dish_select'><option value='zero'>без ничего</option>";
                        foreach ($second_dishes as $dish) {
                            $send_back .= "<option value=".$dish[3]." id=".$dish[3].">".$dish[0]." (<span>".$dish[1]."</span>)</option>";
                        }
                        $send_back .= "</select></td>";
                        $send_back .= "</tr>";
                    }
                }
                $send_back .= "</table>";
                // check whether quantity of second dishes and garnishes is not zero
                // only then user will be able to finish merging  
                if ($count_of_garnirs != 0 && $count_of_second_dishes != 0) {
                    $send_back .= "<div id='finish_merging_div'><a href='#' id='finish_merging'>Готово!</a></div>";
                }
            }
            return $this->renderText(json_encode(array('status' => true, 'garnirs' => $send_back)));
        }
        return $this->renderText(json_encode(array('status' => false)));
    }
    
    /**
     *
     * Function counts same values in multidimentional array
     * returns array of quantity of each value int multidimentional array
     * 
     * @param array $arr
     * @return int 
     */
    public function array_count_values_multidim($arr) { 
        $arr2=array(); 
        foreach($arr as $k=> $v) {
            $tmp = $v[0]."+".$v[1];
            if(!isset($arr2[$tmp])){ 
                $arr2[$tmp]=1; 
            }else{ 
                $arr2[$tmp]++; 
            } 
        } 
        return $arr2;
    }
    
    /**
     * Function merges garnishes and second dishes creating new attribute in session
     * which will contain info about combined orders. Structure of the array, which is putted to the session
     * is the same as 'orders'
     * 
     * json will be returned
     * 
     * 
     * @param sfWebRequest $request
     * @return json 
     */
    public function executeMergeGarnirs(sfWebRequest $request) {
        if($this->getUser()->isAuthenticated() && $request->isXmlHttpRequest()) {
            // get current user
            $user = $this->getUser();  
            
            // get array of combined dishes
            $food = $request->getPostParameter('food');
            
            // sorting array of food by connecting second dish to garnish
            $array_of_food = array();
            foreach ($food as $arr) {
                $second_dish = $arr[0];
                $garnir = $arr[1];
                $array_of_food[] = array($second_dish, $garnir);
            }
            
            // final array that will contain combined orders
            $final_arr = array();
            
            // get count of same values in array
            $res = $this->array_count_values_multidim($array_of_food);
            
            // formulating and preparing an array of combined orders
            foreach ($res as $key => $value) {
                // exploding array of results by garnish id and second dish id
                $tmp_array = explode("+", $key);
                
                // getting second-dish id and garnish id
                $second_dish_id = $tmp_array[0];
                $garnir_id = $tmp_array[1];
                
                // delete garnir from our orders
                if ($user->hasAttribute('orders')) {
                    $orders_garnirs = $user->getAttribute('orders');
                    foreach ($orders_garnirs as $k => $v) {
                        if (is_numeric($second_dish_id) && is_numeric($garnir_id)) {
                            if ($k == $garnir_id || $k == $second_dish_id) {
                                $orders_garnirs[$k][1] -= $value; // decreasing quantity of product in order
                                $product = Doctrine::getTable('products')->findOneBy('id', $k);
                                $price = $product->getPrice();
                                $orders_garnirs[$k][2] -= $price * $value; // decreasing total summary of order
                                if ($orders_garnirs[$k][1] == 0) {
                                    unset($orders_garnirs[$k]);
                                }
                            }
                        }
                    }
                    count($orders_garnirs) == 0 ? $user->setAttribute('orders', false) : $user->setAttribute('orders', $orders_garnirs);
                }
                $quantity = $value;
                // preparing an array to put into the session
                if (is_numeric($second_dish_id) && is_numeric($garnir_id)) {
                    $second_dish = Doctrine::getTable('products')->findOneBy('id', $second_dish_id);
                    $garnir = Doctrine::getTable('products')->findOneBy('id', $garnir_id);
                    $final_arr[$second_dish_id."+".$garnir_id] = array($second_dish->getName() . " + " . $garnir->getName(), $quantity, ($second_dish->getPrice() + $garnir->getPrice()) * $quantity, $second_dish_id."+".$garnir_id, $garnir_id);
                }
            }
             
            // putting array of combined orders into session
            if ($user->hasAttribute('orders_combined')) {
                $orders = $user->getAttribute('orders_combined');
                unset($orders);
                $user->setAttribute('orders_combined', $final_arr);
            }
            else {
                $user->setAttribute('orders_combined', $final_arr);
            }
            return $this->renderText(json_encode(array('status'=> true)));
        }
        return $this->renderText(json_encode(array('status' => false)));
    }
    
    /**
     *
     * Function removes order from table
     * depending on which order user deletes
     * Order can be combined or not
     * 
     * @param sfWebRequest $request
     * @return json 
     */
    public function executeDeleteOrder(sfWebRequest $request) {
        if($this->getUser()->isAuthenticated() && $request->isXmlHttpRequest()) {
            // getting the table to delete from
            $tbl = $request->getPostParameter('tbl');
            // get order id
            $order_id = $request->getPostParameter('oid');
            // removing order from the table
            Doctrine::getTable("$tbl")->findAndRemoveByOrderId($order_id);
            return $this->renderText(json_encode(array('status'=> true)));
        }
        return $this->renderText(json_encode(array('status'=> false)));
    }
}